﻿#include "normaltool.h"
#include "hardtool.h"
#include "reslution.h"
#include<iostream>
#include "../CheckInfor/normalinfor.h"
#include "../CheckInfor/hardinfor.h"
#include <QHostAddress>
#include <QNetworkInterface>
#include <QDebug>

NormalTool* NormalTool::_instance=nullptr;

NormalTool* NormalTool::GetInstance(QObject* parent){
    if(NormalTool::_instance==nullptr)
        NormalTool::_instance=new NormalTool(parent);
    return NormalTool::_instance;
}

NormalTool::~NormalTool(){

}
QStringList GetInforFormCmd(QString cmd) {
    FILE *fp = popen(cmd.toLocal8Bit(),"r");
    QTextStream stream(fp);
    return stream.readAll().split('\n');
}

std::function<void()> NormalTool::GetToolFunction(Yzty::NormalToolCode code){
    std::function<void()> tool;
    switch (code)
    {
        case Yzty::NormalToolCode::SoftLists:
        {
            tool=[this,code](){
                QVector<Yzty::BaceInfor*> infors=NormalTool::GetSoftList();
                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
            };
            break;
        }
        case Yzty::NormalToolCode::IpAddres:
        {
            tool=[this,code](){
                QVector<Yzty::BaceInfor*> infors=NormalTool::GetIpAddressList();
                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
            };
            break;
        }

        case Yzty::NormalToolCode::MirrorFile:
        {
            tool=[this,code](){
                QVector<Yzty::BaceInfor*> infors=NormalTool::GetMirroFile();
                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
            };
            break;
        }
        case Yzty::NormalToolCode::HostInfor:
        {
            tool=[this,code](){
                QVector<Yzty::BaceInfor*> infors=NormalTool::GetHostInfo();
                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
            };
            break;
        }

//        case Yzty::NormalToolCode::HardPart:
//        {
//            tool=[this,code](){
//                QVector<Yzty::BaceInfor*> infors=NormalTool::GetHardPartInfor();
//                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
//            };
//            break;
//        }

        case Yzty::NormalToolCode::PhonePlug:
        {
            tool=[this,code](){
                QVector<Yzty::BaceInfor*> infors=NormalTool::GetPhonePlugInfor();
                NormalInfor::GetInstance()->SubmitInfor(int(code),infors);
            };

            break;
        }

        default:
            break;
    }

    return tool;
}

NormalTool::NormalTool(QObject* parent):QObject (parent){

}

QVector<Yzty::BaceInfor*> NormalTool::GetSoftList(){  //system software list
    return Yzty::Reslution::GetInstance()->GetSoftListFromCmd();
}


QVector<Yzty::BaceInfor*> NormalTool::GetIpAddressList(){
    QVector<Yzty::BaceInfor*> res;
    for(QHostAddress addr:QNetworkInterface::allAddresses()){
        Yzty::IpAddressInfor* infor=new Yzty::IpAddressInfor(quint16(Yzty::NormalToolCode::IpAddres));
        infor->_infors[Yzty::IpAddressInfor::Ip]=addr.toString();
        infor->_infors[Yzty::IpAddressInfor::Type]=addr.protocol()==QAbstractSocket::IPv4Protocol?
                    "IPV4":"IPV6";
        res.push_back(infor);
    }
    return res;
}

//获取镜像文件
QVector<QFileInfo> GetDirFileInfor(QDir dir){
    static QStringList types={
        "ISO","BIN","IMG","TAO","DAO","CIF","FCD"
    };

    QDir::Filters flag=QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot;
    QVector<QFileInfo> res;

    for(QFileInfo infor:dir.entryInfoList(flag)){
        if(infor.isDir()){
            QVector<QFileInfo> temp=GetDirFileInfor(infor.filePath());
            res.append(temp);
        }else if(types.contains(infor.suffix().toUpper()))
//            if(infor.size()>1000)
            res.push_back(infor);
    }
    return res;
}


QVector<Yzty::BaceInfor*> NormalTool::GetMirroFile(){
   QDir dir(QDir::homePath());     //默认路径
 //   QDir dir(QDir::root());
    QVector<QFileInfo>&& files=GetDirFileInfor(dir);
    QVector<Yzty::BaceInfor*> infors;
    qDebug()<<files.size();
    int size;
    for(QFileInfo& file:files){
        size=file.size()/(1024*1024);
        Yzty::MirrorFile* infor=new Yzty::MirrorFile(uint16_t(Yzty::NormalToolCode::MirrorFile));
        infor->_infors[Yzty::MirrorFile::Name]=file.fileName();
        infor->_infors[Yzty::MirrorFile::Path]=file.filePath();
        infor->_infors[Yzty::MirrorFile::Type]=file.suffix();
        infor->_infors[Yzty::MirrorFile::Size]=QString::number(size);
        infors.push_back(infor);
    }    return infors;
}

QVector<Yzty::BaceInfor*> NormalTool::GetHostInfo() {
    QVector<Yzty::BaceInfor*> result;
    Yzty::HostInfor* allinfor=new Yzty::HostInfor(quint16(Yzty::NormalToolCode::HostInfor));
    //计算机信息部分
    QString cmd = "sudo lscpu";//cpu信息
    QString cmd1 = "sudo dmidecode -s 'baseboard-product-name'&&sudo dmidecode -s 'baseboard-serial-number'";//主板型号和序列号
    QString cmd2 = "sudo cat /proc/meminfo|grep MemTotal:";//内存总和
    QString cmd3 = "sudo dmidecode -s 'system-product-name'";//电脑型号
    QString cmd4 = "sudo hostname";//计算机名
    QStringList infors = GetInforFormCmd(cmd);
    Yzty::ComputerInfo* computerinfor=new Yzty::ComputerInfo();
    for(QString temp:infors) {
        if(temp.startsWith("Model name:")) { //处理器
            computerinfor->_infors[Yzty::ComputerInfo::CPUNAME].Information = temp.split(':').last().simplified();
        }
        else if(temp.startsWith("CPU MHz:")) {
            computerinfor->_infors[Yzty::ComputerInfo::CPURATE].Information = temp.split(' ').last()+"Mhz";
        }
        else if(temp.startsWith("Core(s) per socket:")) {
            computerinfor->_infors[Yzty::ComputerInfo::CORENUM].Information = temp.split(' ').last();
        }
        else if(temp.startsWith("CPU(s):")) {
            computerinfor->_infors[Yzty::ComputerInfo::LOGICCORENUM].Information = temp.split(' ').last();
        }
    }
    infors = GetInforFormCmd(cmd1);
    computerinfor->_infors[Yzty::ComputerInfo::MAINBOARD].Information = infors.first();
    if(infors.size()>=2) {
        computerinfor->_infors[Yzty::ComputerInfo::MAINBOARD].Serialnum = infors.value(1);
    }
    infors = GetInforFormCmd(cmd2);
    computerinfor->_infors[Yzty::ComputerInfo::MEMORYINFO].Information = QString::number(infors.first().simplified().split(' ').value(1).toInt()/1024);
    infors = GetInforFormCmd(cmd3);
    computerinfor->_infors[Yzty::ComputerInfo::MODEL].Information = infors.first();
    infors = GetInforFormCmd(cmd4);
    computerinfor->_infors[Yzty::ComputerInfo::COMPUTERNAME].Information = infors.first();
    allinfor->computerinfor = computerinfor;
    //内存信息
    const std::vector<Yzty::BaceInfor*>& old_memoryinfor=HardInfor::GetInstance()->GetNormalCheck(Yzty::HardToolCode::Memory);
    for(size_t i=0;i<old_memoryinfor.size();i++) {
        Yzty::MemoryInfor* memoryinfor=new Yzty::MemoryInfor();
        memoryinfor->_infors[Yzty::MemoryInfor::RATE].Information = old_memoryinfor[i]->GetItem(7);//频率
        memoryinfor->_infors[Yzty::MemoryInfor::MODEL].Information = old_memoryinfor[i]->GetItem(2);//型号
        memoryinfor->_infors[Yzty::MemoryInfor::MODEL].Serialnum = old_memoryinfor[i]->GetItem(4);//序列号
        memoryinfor->_infors[Yzty::MemoryInfor::CAPACITY].Information = old_memoryinfor[i]->GetItem(3);//容量
        memoryinfor->_infors[Yzty::MemoryInfor::VENDERNAME].Information = old_memoryinfor[i]->GetItem(1);//制造商
        allinfor->memoryinfors.push_back(memoryinfor);
    }
    //网卡信息
    const std::vector<Yzty::BaceInfor*>& old_netinfor=HardInfor::GetInstance()->GetNormalCheck(Yzty::HardToolCode::NetCard);
    QString netcmd1 = "sudo cat /etc/resolv.conf|grep nameserver";//DNS
    QString netcmd2 = "sudo route -n|grep -A 10 Destination";//网关信息
    QStringList netinfor1 = GetInforFormCmd(netcmd1);
    QStringList netinfor2 = GetInforFormCmd(netcmd2);
    QVector<QStringList> tem_gateway;
    for(QString temp:netinfor2) {
        tem_gateway.push_back(temp.simplified().split(' '));
    }
    /*Local name接入过来，加到网关信息*/
    for(size_t i=0;i<old_netinfor.size();i++) {
        QString gateway = "";//网关信息
        Yzty::NetInfor* netinfor=new Yzty::NetInfor();
        QStringList tem_driverinfor = old_netinfor[i]->GetItem(7).split(' ').filter("driver=");
        QStringList tem_ipinfor = old_netinfor[i]->GetItem(7).split(' ').filter("ip=");
        netinfor->_infors[Yzty::NetInfor::NAME].Information = old_netinfor[i]->GetItem(0);   //名称
        netinfor->_infors[Yzty::NetInfor::INFOR].Information = old_netinfor[i]->GetItem(6); //网卡信息
        netinfor->_infors[Yzty::NetInfor::DRIVER].Information = tem_driverinfor.size()!=0? tem_driverinfor.first().split('=').last():""; //驱动信息
        netinfor->_infors[Yzty::NetInfor::IP].Information = tem_ipinfor.size()!=0 ? tem_ipinfor.first().split('=').last():"--";//IP
        netinfor->_infors[Yzty::NetInfor::MAC].Information = old_netinfor[i]->GetItem(9); //当前MAC
        netinfor->_infors[Yzty::NetInfor::DNS].Information = netinfor1.size() >=1 ? netinfor1.first().split(' ').last(): "--";
        for(QStringList temp:tem_gateway) {
            if(temp.value(0)=="0.0.0.0"&&temp.value(7)==old_netinfor[i]->GetItem(10)) {
                gateway = temp.value(1);
                break;
            }
        }
        netinfor->_infors[Yzty::NetInfor::GATEWAY].Information = gateway != "" ? gateway:"--";
        allinfor->netinfors.push_back(netinfor);
    }
    result.push_back(allinfor);
    return result;
}

QVector<Yzty::BaceInfor*> NormalTool::GetHardPartInfor()
{
    QString cmd1="df -Th|grep '/dev/nvme0n1'";
    QString cmd2="sudo fdisk -l|grep -A 30 'Device'";
    QVector<Yzty::BaceInfor*> result;
    FILE* fp1=popen(cmd1.toLocal8Bit(),"r");
    if(fp1==nullptr)
        return result;
    FILE* fp2=popen(cmd2.toLocal8Bit(),"r");
    if(fp2==nullptr)
        return result;
    QTextStream fstream1(fp1);
    QStringList infors1=fstream1.readAll().split('\n');
    QTextStream fstream2(fp2);
    QStringList infors2=fstream2.readAll().split('\n');
    Yzty::HardPartInfor *hard[infors2.length()-1];
    for(int i=0;i<infors2.length()-1;i++)
        hard[i]=new Yzty::HardPartInfor(uint16_t(Yzty::NormalToolCode::HardPart));
    for(int i=0;i<infors2.length()-1;i++)  //去除最后一行
    {
        if(infors2[i].startsWith("Device"))//去除表头
            continue;
        QStringList inforss = infors2[i].simplified().split(' ');
        QString describe;//存入描述休息
        int infor_size = inforss[0].length();
        QByteArray inforss2=inforss[0].toLatin1();
        if(infor_size==14)
        {
            for(int i = 5;i<infor_size;i++){//从第六个单词开始接到字符串后面
                describe=describe+inforss2[i];
            }
        }
        hard[i]->_infors[Yzty::HardPartInfor::Partittion]=describe;
        hard[i]->_infors[Yzty::HardPartInfor::Total]=inforss[4];
        result.push_back(hard[i]);
    }


    for(int i=0;i<infors1.length();i++)
    {
          QStringList temp1=infors1[i].simplified().split(' ');
          for(int i=1;i<infors2.length()-1;i++)
          {
              if(temp1[0].contains(hard[i]->_infors[Yzty::HardPartInfor::Partittion]))
              {
                  hard[i]->_infors[Yzty::HardPartInfor::Used]=temp1[3];
                  hard[i]->_infors[Yzty::HardPartInfor::Usable]=temp1[4];
                  hard[i]->_infors[Yzty::HardPartInfor::Type]=temp1[1];
              }
          }
          result.push_back(hard[i]);

    }
    return result;
}

QVector<Yzty::BaceInfor*> NormalTool::GetPhonePlugInfor()
{
    QStringList Manufacturers{//手机厂商
        "Xiaomi",
        "huawei",
        "oppo",
        "vivo",
        "lenovo",
        "ZTE",
        "honor",
        "meizu",
        "apple",
        "samsung",
        "oneplus",
        "nubia",
        "sony",
        "motorola",
        "nokia",
        "htc",
        "realme",
        "iqoo"
    };
    QString cmd="sudo dmesg -T|grep '] usb'";
    QVector<Yzty::BaceInfor*> result;
    QStringList infors = GetInforFormCmd(cmd);
    QString strTime = "";
    QString strDes = "";
    QString strnewDes = "";
    QString strNewTime = "";
    QHash<int,Yzty::PhonePlugInfor*> map_infors;
    int devicecode;//设备号
    Yzty::PhonePlugInfor *item;
    for(QString tem:infors) {
        strNewTime = tem.split("] ").first();
        QStringList info = tem.split(' ');
        if(info.size() >= 5)
            strnewDes = info[5];

        if(strNewTime == strTime&&strDes == strNewTime&&map_infors.find(devicecode)!=map_infors.end()) {//时间相同行
            if(tem.contains("idVendor=")) {
                QStringList l = tem.split(", ");
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::idVendor] = l[1].split('=').last();
            }
            if(tem.contains("idProduct=")) {
                QStringList l = tem.split(", ");
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::idProduct] = l[2].split('=').last();
            }
            if(tem.contains(" Product: ")) {
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::Product] = tem.split(": ").last();
            }
            if(tem.contains(" Manufacturer: ")) {
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::Manufacturer] = tem.split(": ").last();
            }
            if(tem.contains(" SerialNumber: ")) {
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::SerialNumber] = tem.split(": ").last();
            }
        }
        else {//遇到新时间
            strTime = strNewTime;
            strDes = strNewTime;
            if(tem.contains(" USB device number ")&&tem.contains("new")) {
                item = new Yzty::PhonePlugInfor(uint16_t(Yzty::NormalToolCode::HardPart));
                QString str = tem.split("device number ").last();
                devicecode = str.split(' ').first().toInt();
                map_infors.insert(devicecode,item);
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::FirstTime] = strNewTime.replace('[',"");
                map_infors[devicecode]->_infors[Yzty::PhonePlugInfor::DeviceAttech] = "已连接";
            }
            else if(tem.contains("USB disconnect, device number")) {//断开连接
                int code = tem.split("USB disconnect, device number ").last().toInt();
                if(map_infors.find(code) != map_infors.end()) {
                    map_infors[code]->_infors[Yzty::PhonePlugInfor::LastTime] = strNewTime.replace('[',"");
                    map_infors[code]->_infors[Yzty::PhonePlugInfor::DeviceAttech] = "未连接";
                }
            }
        }
    }
    auto it = map_infors.begin();
    while(it!=map_infors.end()) {//筛选手机
        if(Manufacturers.contains( it.value()->_infors[Yzty::PhonePlugInfor::Manufacturer],Qt::CaseInsensitive)){
            it.value()->_infors[Yzty::PhonePlugInfor::DeciceType] = "手机";
            result.push_back(it.value());
        }

        it++;
    }
    return result;
}
